#include "sdk.h"
#ifndef CB_PRECOMP
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/event.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/xrc/xmlres.h>
#include "globals.h"
#include "manager.h"
#include "configmanager.h"
#endif

#ifdef TRACE_SYMTAB_CFG
#ifndef CB_PRECOMP
#include "logmanager.h"
#endif
#endif

#include <wx/dirdlg.h>
#include <wx/filedlg.h>
#include "symtabconfig.h"
#include "prep.h"

BEGIN_EVENT_TABLE( SymTabConfigDlg, wxScrollingDialog )
  EVT_BUTTON( XRCID( "btnSearch" ),      SymTabConfigDlg::OnSearch )
  EVT_BUTTON( XRCID( "btnClose" ),       SymTabConfigDlg::OnClose )
  EVT_CHOICE( XRCID( "choWhatToDo" ),    SymTabConfigDlg::OnWhatToDo )
  EVT_BUTTON( XRCID( "btnLibraryPath" ), SymTabConfigDlg::OnLibraryPath )
  EVT_BUTTON( XRCID( "btnLibrary" ),     SymTabConfigDlg::OnLibrary )
  EVT_BUTTON( XRCID( "btnNM" ),          SymTabConfigDlg::OnNM )
END_EVENT_TABLE()

SymTabConfigDlg::~SymTabConfigDlg() {
}

int SymTabConfigDlg::Execute() {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::Execute" ) ) );
  #endif
  if( !SymTabConfigDlgLoaded ) {
    SymTabConfigDlgLoaded =
      wxXmlResource::Get()->LoadObject( this, parent, _T( "dlgSymTabConfig" ), _T( "wxScrollingDialog" ) );
  }
  LoadSettings();
  return wxScrollingDialog::ShowModal();
}




void SymTabConfigDlg::EndModal( int retCode ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::EndModal" ) ) );
  #endif
  wxScrollingDialog::EndModal( retCode );
}


void SymTabConfigDlg::OnWhatToDo( wxCommandEvent& event ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnWhatToDo" ) ) );
  #endif
  int choice = event.GetInt();
  ToggleWidgets( choice );
}


void SymTabConfigDlg::OnSearch( wxCommandEvent& ( event ) ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnSearch" ) ) );
  #endif
  SaveSettings();
  ConfigManager* cfg = Manager::Get()->GetConfigManager( _T( "symtab" ) );
  int choice = cfg->ReadInt( _T( "/what_to_do" ), 0 );
  if( choice == 0 ) {
    wxString library_path = ( cfg->Read( _T( "/library_path" ) ) ).Trim();
    if( library_path.IsEmpty() ) {
      msging( _( "No library path provided." ), _( "错误" ), wxICON_ERROR | wxOK,
              ( wxWindow* )Manager::Get()->GetAppWindow() );
      return;
    }
    if( !( cfg->ReadBool( _T( "/include_a" ),   true )
           || cfg->ReadBool( _T( "/include_lib" ), true )
           || cfg->ReadBool( _T( "/include_o" ),   false )
           || cfg->ReadBool( _T( "/include_obj" ), false )
           || cfg->ReadBool( _T( "/include_so" ),  false )
           || cfg->ReadBool( _T( "/include_dll" ), false ) ) ) {
      msging( _( "No file type (include) provided." ), _( "错误" ), wxICON_ERROR | wxOK,
              ( wxWindow* )Manager::Get()->GetAppWindow() );
      return;
    }
    wxString symbol = ( cfg->Read( _T( "/symbol" ) ) ).Trim();
    if( symbol.IsEmpty() ) {
      wxString msg;
      msg << _( "Warning: You did not select a symbol to search for in a path.\n" )
          << _( "You may operate on many files - this can be a lengthy operation.\n" )
          << _( "Are you really sure that you want to do this?" );
      if( msging( msg, _( "Warning" ), wxICON_WARNING | wxYES_NO,
                  ( wxWindow* )Manager::Get()->GetAppWindow() ) == wxID_NO )
      { return; }
    }
  } else if( choice == 1 ) {
    wxString library = ( cfg->Read( _T( "/library" ) ) ).Trim();
    if( library.IsEmpty() ) {
      msging( _( "No library provided." ), _( "错误" ), wxICON_ERROR | wxOK,
              ( wxWindow* )Manager::Get()->GetAppWindow() );
      return;
    }
  }
  wxScrollingDialog::EndModal( wxID_OK );
}


void SymTabConfigDlg::OnClose( wxCommandEvent& ( event ) ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnClose" ) ) );
  #endif
  wxScrollingDialog::EndModal( wxID_CANCEL );
}


void SymTabConfigDlg::OnLibraryPath( wxCommandEvent& ( event ) ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnLibraryPath" ) ) );
  #endif
  wxDirDialog dd( parent, _( "Select directory for search" ) );
  if( dd.ShowModal() == wxID_OK ) {
    wxString path = dd.GetPath();
    XRCCTRL( *this, "txtLibraryPath", wxTextCtrl )->SetValue( path );
  }
}


void SymTabConfigDlg::OnLibrary( wxCommandEvent& ( event ) ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnLibrary" ) ) );
  #endif
  wxString caption  = _T( "Choose a (library) file" );
  wxString wildcard;
  wildcard << _T( "Library files (*.a)|*.a|" )
           << _T( "Library files (*.lib)|*.lib|" )
           << _T( "Object files (*.o)|*.o|" )
           << _T( "Object files (*.obj)|*.obj|" )
           << _T( "Shared object files (*.so)|*.so|" )
           << _T( "Dynamic link library files (*.dll)|*.dll|" )
           << _T( "All files (*)|*" );
  wxString es       = wxEmptyString;
  wxFileDialog fd( parent, caption, es, es, wildcard, wxFD_OPEN | compatibility::wxHideReadonly );
  if( fd.ShowModal() == wxID_OK ) {
    wxString path = fd.GetPath();
    XRCCTRL( *this, "txtLibrary", wxTextCtrl )->SetValue( path );
  }
}


void SymTabConfigDlg::OnNM( wxCommandEvent& ( event ) ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::OnNM" ) ) );
  #endif
  wxString caption  = _T( "Choose NM application" );
  wxString wildcard;
  wildcard = _T( "All files (*)|*" );
  wxString es = wxEmptyString;
  wxFileDialog fd( parent, caption, es, es, wildcard, wxFD_OPEN | compatibility::wxHideReadonly );
  if( fd.ShowModal() == wxID_OK ) {
    wxString path = fd.GetPath();
    XRCCTRL( *this, "txtNM", wxTextCtrl )->SetValue( path );
  }
}


void SymTabConfigDlg::ToggleWidgets( int choice ) {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::ToggleWidgets" ) ) );
  #endif
  XRCCTRL( *this, "txtLibraryPath", wxTextCtrl )->Enable( false );
  XRCCTRL( *this, "btnLibraryPath", wxButton )->Enable( false );
  XRCCTRL( *this, "chkIncludeA",    wxCheckBox )->Enable( false );
  XRCCTRL( *this, "chkIncludeLib",  wxCheckBox )->Enable( false );
  XRCCTRL( *this, "chkIncludeO",    wxCheckBox )->Enable( false );
  XRCCTRL( *this, "chkIncludeObj",  wxCheckBox )->Enable( false );
  XRCCTRL( *this, "chkIncludeSo",   wxCheckBox )->Enable( false );
  XRCCTRL( *this, "chkIncludeDll",  wxCheckBox )->Enable( false );
  XRCCTRL( *this, "txtLibrary",     wxTextCtrl )->Enable( false );
  XRCCTRL( *this, "btnLibrary",     wxButton )->Enable( false );
  if( choice == 0 ) {
    XRCCTRL( *this, "txtLibraryPath", wxTextCtrl )->Enable( true );
    XRCCTRL( *this, "btnLibraryPath", wxButton )->Enable( true );
    XRCCTRL( *this, "chkIncludeA",    wxCheckBox )->Enable( true );
    XRCCTRL( *this, "chkIncludeLib",  wxCheckBox )->Enable( true );
    XRCCTRL( *this, "chkIncludeO",    wxCheckBox )->Enable( true );
    XRCCTRL( *this, "chkIncludeObj",  wxCheckBox )->Enable( true );
    XRCCTRL( *this, "chkIncludeSo",   wxCheckBox )->Enable( true );
    XRCCTRL( *this, "chkIncludeDll",  wxCheckBox )->Enable( true );
  } else if( choice == 1 ) {
    XRCCTRL( *this, "txtLibrary",     wxTextCtrl )->Enable( true );
    XRCCTRL( *this, "btnLibrary",     wxButton )->Enable( true );
  }
}


void SymTabConfigDlg::LoadSettings() {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::LoadSettings" ) ) );
  #endif
  ConfigManager* cfg = Manager::Get()->GetConfigManager( _T( "symtab" ) );
  int choice = cfg->ReadInt( _T( "/what_to_do" ), 0 );
  XRCCTRL( *this, "choWhatToDo",     wxChoice )->SetSelection( choice );
  ToggleWidgets( choice );
  XRCCTRL( *this, "txtLibraryPath",    wxTextCtrl )->SetValue(
    cfg->Read( _T( "/library_path" ),    _T( "" ) ) );
  XRCCTRL( *this, "chkIncludeA",       wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_a" ),   true ) );
  XRCCTRL( *this, "chkIncludeLib",     wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_lib" ), true ) );
  XRCCTRL( *this, "chkIncludeO",       wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_o" ),   false ) );
  XRCCTRL( *this, "chkIncludeObj",     wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_obj" ), false ) );
  XRCCTRL( *this, "chkIncludeSo",      wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_so" ),  false ) );
  XRCCTRL( *this, "chkIncludeDll",     wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/include_dll" ), false ) );
  XRCCTRL( *this, "txtLibrary",        wxTextCtrl )->SetValue(
    cfg->Read( _T( "/library" ),         _T( "" ) ) );
  XRCCTRL( *this, "txtSymbol",         wxTextCtrl )->SetValue(
    cfg->Read( _T( "/symbol" ),          _T( "" ) ) );
  XRCCTRL( *this, "txtNM",             wxTextCtrl )->SetValue(
    cfg->Read( _T( "/nm" ),              _T( "" ) ) );
  XRCCTRL( *this, "chkDebug",          wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/debug" ),       false ) );
  XRCCTRL( *this, "chkDefined",        wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/defined" ),     false ) );
  XRCCTRL( *this, "chkDemangle",       wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/demangle" ),    false ) );
  XRCCTRL( *this, "chkExtern",         wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/extern" ),      false ) );
  XRCCTRL( *this, "chkSpecial",        wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/special" ),     false ) );
  XRCCTRL( *this, "chkSynthetic",      wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/synthetic" ),   false ) );
  XRCCTRL( *this, "chkUndefined",      wxCheckBox )->SetValue(
    cfg->ReadBool( _T( "/undefined" ),   false ) );
}


void SymTabConfigDlg::SaveSettings() {
  #ifdef TRACE_SYMTAB_CFG
  Manager::Get()->GetLogManager()->DebugLog( F( _T( "SymTabConfigDlg::SaveSettings" ) ) );
  #endif
  ConfigManager* cfg = Manager::Get()->GetConfigManager( _T( "symtab" ) );
  cfg->Write( _T( "/what_to_do" ),
              XRCCTRL( *this, "choWhatToDo",    wxChoice )->GetSelection() );
  cfg->Write( _T( "/library_path" ),
              XRCCTRL( *this, "txtLibraryPath", wxTextCtrl )->GetValue().Trim() );
  cfg->Write( _T( "/include_a" ),
              XRCCTRL( *this, "chkIncludeA",    wxCheckBox )->GetValue() );
  cfg->Write( _T( "/include_lib" ),
              XRCCTRL( *this, "chkIncludeLib",  wxCheckBox )->GetValue() );
  cfg->Write( _T( "/include_o" ),
              XRCCTRL( *this, "chkIncludeO",    wxCheckBox )->GetValue() );
  cfg->Write( _T( "/include_obj" ),
              XRCCTRL( *this, "chkIncludeObj",  wxCheckBox )->GetValue() );
  cfg->Write( _T( "/include_so" ),
              XRCCTRL( *this, "chkIncludeSo",   wxCheckBox )->GetValue() );
  cfg->Write( _T( "/include_dll" ),
              XRCCTRL( *this, "chkIncludeDll",  wxCheckBox )->GetValue() );
  cfg->Write( _T( "/library" ),
              XRCCTRL( *this, "txtLibrary",     wxTextCtrl )->GetValue().Trim() );
  cfg->Write( _T( "/symbol" ),
              XRCCTRL( *this, "txtSymbol",      wxTextCtrl )->GetValue().Trim() );
  cfg->Write( _T( "/nm" ),
              XRCCTRL( *this, "txtNM",          wxTextCtrl )->GetValue().Trim() );
  cfg->Write( _T( "/debug" ),
              XRCCTRL( *this, "chkDebug",       wxCheckBox )->GetValue() );
  cfg->Write( _T( "/defined" ),
              XRCCTRL( *this, "chkDefined",     wxCheckBox )->GetValue() );
  cfg->Write( _T( "/demangle" ),
              XRCCTRL( *this, "chkDemangle",    wxCheckBox )->GetValue() );
  cfg->Write( _T( "/extern" ),
              XRCCTRL( *this, "chkExtern",      wxCheckBox )->GetValue() );
  cfg->Write( _T( "/special" ),
              XRCCTRL( *this, "chkSpecial",     wxCheckBox )->GetValue() );
  cfg->Write( _T( "/synthetic" ),
              XRCCTRL( *this, "chkSynthetic",   wxCheckBox )->GetValue() );
  cfg->Write( _T( "/undefined" ),
              XRCCTRL( *this, "chkUndefined",   wxCheckBox )->GetValue() );
}
